import axios, { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig, AxiosRequestConfig } from "axios";
import { IApiResponse } from "@/types/api";
import { Message } from "@arco-design/web-vue";
import router from "@/router";

const instance: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || "",
  withCredentials: true,
  timeout: 60000,
});

const requestMap = new Map<string, AbortController>();

// 请求拦截器
instance.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const controller = new AbortController();
    config.signal = controller.signal;
    // 将 AbortController 存储在 Map 中，key 为 URL
    requestMap.set(config.url as string, controller);
    return config;
  },
  (error) => {
    console.error(error);
    return Promise.reject(error);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  (response: AxiosResponse) => {
    requestMap.delete(response.config.url as string);
    // 文件流类型
    if (response.data instanceof Blob) {
      return response;
    }
    if (response.data?.status === 200) {
      return response;
    }
    // 登陆过期
    if (response.data?.status === 401) {
      removeAllRequests(); // 取消正在发送的请求
      Message.error(response.data?.msg || "未知错误");
      router.push({ name: "LOGIN" });
      return Promise.reject(response.data?.msg || "未知错误");
    }

    Message.error(response.data?.msg || "未知错误");
    return Promise.reject(response.data?.msg || "未知错误");
  },
  (error) => {
    return Promise.reject(error);
  }
);

const request = async <T = any>(config: AxiosRequestConfig): Promise<IApiResponse<T>> => {
  // eslint-disable-next-line no-useless-catch
  try {
    const { data } = await instance.request<IApiResponse<T>>(config);
    return data;
  } catch (err) {
    throw err;
  }
};

// 取消所有请求
export const removeAllRequests = () => {
  if (requestMap.size === 0) return;
  requestMap.forEach((controller: AbortController) => {
    controller.abort();
  });
  requestMap.clear();
};

// 取消上一次请求
export const removeLastRequest = () => {
  if (requestMap.size === 0) return;
  const requests = Array.from(requestMap);
  const lastRequest: [string, AbortController] = requests[requests.length - 1];
  lastRequest[1].abort();
  requestMap.delete(lastRequest[0]);
};

export default request;
